using System;
using System.Collections.Generic;
using System.Text;

using System.Drawing;
using System.Security.Cryptography;

namespace PictureMimic
{
	public interface CandidateDominanceModel
	{
		CandidateGene GetDominant(CandidateGene paternalGene, CandidateGene maternalGene, CandidateDNA paternalDNA, CandidateDNA maternalDNA);
	}

	/*** Dominance decided by a coin flip. ***/
	public class CoinFlipDominance : CandidateDominanceModel
	{
		public CandidateGene GetDominant(CandidateGene paternalGene, CandidateGene maternalGene, CandidateDNA paternalDNA, CandidateDNA maternalDNA)
		{
			CandidateGene dominant;

			byte[] seed;
			RNGCryptoServiceProvider seeder;
			Random randomiser;

			seed = new byte[32];
			seeder = new RNGCryptoServiceProvider();
			seeder.GetBytes(seed);

			randomiser = new Random((int)BitConverter.ToInt32(seed, 0));

			if (randomiser.Next(0, 2) < 1)
			{
				dominant = paternalGene;
			}
			else
			{
				dominant = maternalGene;
			}

			return dominant;
		}
	}

	/*** Genes inherited from father are always dominant. ***/
	public class PaternalDominance : CandidateDominanceModel
	{
		public CandidateGene GetDominant(CandidateGene paternalGene, CandidateGene maternalGene, CandidateDNA paternalDNA, CandidateDNA maternalDNA)
		{
			return paternalGene;
		}
	}

	/*** Genes inherited from mother are always dominant. ***/
	public class MaternalDominance : CandidateDominanceModel
	{
		public CandidateGene GetDominant(CandidateGene paternalGene, CandidateGene maternalGene, CandidateDNA paternalDNA, CandidateDNA maternalDNA)
		{
			return maternalGene;
		}
	}

	/*** Genes inherited from fitest parent are always dominant. ***/
	public class FitnessDominance : CandidateDominanceModel
	{
		public CandidateGene GetDominant(CandidateGene paternalGene, CandidateGene maternalGene, CandidateDNA paternalDNA, CandidateDNA maternalDNA)
		{
			CandidateGene dominant;

			if (paternalDNA.Fitness < maternalDNA.Fitness)
			{
				// This is correct. The lower the fitness the better.
				// This is because fitness is a measure of difference.
				// We could reverse it, but it is a wasted calculation.
				dominant = paternalGene;
			}
			else
			{
				dominant = maternalGene;
			}

			return dominant;
		}
	}
}
